﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.Reflection;

namespace WorkflowManagement.Web.UI
{
    /// <summary>
    /// A class that provides support for executing the specified workflow when an event is raised.
    /// </summary>
    public class EventWorkflowTrigger: WorkflowTrigger
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="EventWorkflowTrigger"/> class.
        /// </summary>
        public EventWorkflowTrigger()
        {
        }

        private string controlId;

        /// <summary>
        /// Gets or sets the id of the control containing the event.
        /// </summary>
        /// <value>The control id.</value>
        [IDReferenceProperty]
        public string ControlId
        {
            get { return controlId; }
            set { controlId = value; }
        }

        private string eventName;

        /// <summary>
        /// Gets or sets the name of the event.
        /// </summary>
        /// <value>The name of the event.</value>
        public string EventName
        {
            get { return eventName; }
            set { eventName = value; }
        }

        /// <summary>
        /// Initializes this trigger.
        /// </summary>
        protected override void Initialize()
        {
            Control control = Manager.NamingContainer.FindControl(controlId);
            
            if (control == null)
                throw new InvalidOperationException();
                
            Type type = control.GetType();
            
            EventInfo eventInfo = type.GetEvent(eventName);
            
            if (eventInfo == null)
                throw new InvalidOperationException();
                
            eventInfo.AddEventHandler(control, Delegate.CreateDelegate(eventInfo.EventHandlerType, this, "EventRaised"));
        }

        /// <summary>
        /// A delegate bridging the trigger with the target controls event.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Used by reflection binding.")]
        private void EventRaised(object sender, EventArgs e)
        {
            OnTrigger();
        }
    }
}
